<?php

namespace app\common\model\common;

use app\common\model\CommonBaseModel;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;

class OperateLog extends CommonBaseModel
{
    /*
    CREATE TABLE `operate_log` (
      `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'id',
      `category` varchar(50) NOT NULL COMMENT '业务类别',
      `data_id` int(11) NOT NULL COMMENT '业务类别对应的数据id',
      `operate_type` tinyint(1) NOT NULL COMMENT '操作类型: 1添加，2修改，3删除',
      `before_data` text COMMENT '修改前数据',
      `after_data` text COMMENT '修改后数据',
      `creator_id` int(11) NOT NULL DEFAULT '0' COMMENT '创建人id',
      `add_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '添加时间',
      PRIMARY KEY (`id`),
      KEY `table_name_id` (`category`,`data_id`) COMMENT '关联数据表名和数据id'
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='通用操作日志表';
    */

    //operate_log.category
    const CATEGORY_USER = 'user';

    //operate_log.operate_type:操作类型: 1添加，2修改，3删除
    const OPERATE_TYPE_ADD = 1;
    const OPERATE_TYPE_MODIFY = 2;
    const OPERATE_TYPE_DELETE = 3;

    /**
     * 获取指定类别的operate_log数据
     * @param string $category 业务类别
     * @param int $data_id 业务类别对应的数据id
     * @param array $log_field_map
     * @return array
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public static function getOperateLog(string $category, int $data_id, array $log_field_map = [])
    {
        $where = ['category' => $category, 'data_id' => $data_id];
        $list = parent::where($where)->order('id', 'desc')->select()->toArray();
        if (empty($list)) {
            return [];
        }

        foreach ($list as &$v) {
            $log_detail = [];

            $before_data_temp = json_decode($v['before_data'], true);
            foreach ($before_data_temp as $ka => $va) {
                $label = $log_field_map[$ka]['label'] ?? $ka;
                $format = $log_field_map[$ka]['format'] ?? [];
                if (!empty($format)) {
                    $va = $format[$va] ?? $va;
                }

                $log_detail[$ka]['label'] = $label;
                $log_detail[$ka]['old_value'] = $va;
                $log_detail[$ka]['new_value'] = '';
            }

            $after_data_temp = json_decode($v['after_data'], true);
            foreach ($after_data_temp as $ka => $va) {
                $label = $log_field_map[$ka]['label'] ?? $ka;
                $format = $log_field_map[$ka]['format'] ?? [];
                if (!empty($format)) {
                    $va = $format[$va] ?? $va;
                }

                if (empty($log_detail[$ka]['label'])) {
                    $log_detail[$ka]['label'] = $label;
                }
                if (empty($log_detail[$ka]['old_value'])) {
                    $log_detail[$ka]['old_value'] = '';
                }
                $log_detail[$ka]['new_value'] = $va;
            }

            $v['log_detail'] = array_values($log_detail);
            unset($v['before_data']);
            unset($v['after_data']);
            unset($v['category']);
        }
        return $list;
    }

    /**
     * 执行添加operate_log数据
     * @param string $category 业务类别
     * @param int $data_id 业务类别对应的数据id
     * @param array $before_data 修改前的数据
     * @param array $after_data 修改后的数据
     * @return void
     */
    public static function addOperateLog(string $category, int $data_id, array $before_data, array $after_data)
    {
        if (empty($before_data)) {
            $operate_type = self::OPERATE_TYPE_ADD;
        } elseif (empty($after_data)) {
            $operate_type = self::OPERATE_TYPE_DELETE;
        } else {
            $operate_type = self::OPERATE_TYPE_MODIFY;
        }

        $creator_id = 1; //todo 获取当前登录的用户
        $commonLogData = [
            'category' => $category,
            'data_id' => $data_id,
            'operate_type' => $operate_type,
            'before_data' => echoJson($before_data),
            'after_data' => echoJson($after_data),
            'creator_id' => $creator_id,
        ];
        parent::insert($commonLogData);
    }
}